#include <bits/stdc++.h>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <cctype>
#include <random>
using namespace std;

mt19937 rand_main;
string generate_random_name() {
    string name;
    name += 'a' + (rand_main() % 26);
    for (int i = 0; i < 15; ++i) {
        int val = rand_main() % 36;
        name += (val < 10) ? ('0' + val) : ('a' + (val - 10));
    }
    return "_"+name;
}

bool is_valid_identifier(const string& token) {
    if (token.empty()) return false;
    if (!isalpha(token[0]) && token[0] != '_') return false;
    return all_of(token.begin(), token.end(), [](char c) {
        return isalnum(c) || c == '_';
    });
}

void process_content(string& content) {
    map<string, string> name_map;
    stringstream result;
    bool in_string = false;
    bool in_comment = false;
    bool in_macro = false;
    bool in_preprocessor = false;
    string current_token;
    char last_char = 0;
    char quote_char = 0;
    
    auto is_unescaped_quote = [&](size_t pos) {
        int backslash_count = 0;
        for (int j = (int)pos - 1; j >= 0 && content[j] == '\\'; --j) {
            backslash_count++;
        }
        return (backslash_count % 2 == 0);
    };

    for (size_t i = 0; i < content.size(); ++i) {
        char c = content[i];
        
        if ((c == '"' || c == '\'') && is_unescaped_quote(i)) {
            if (!in_string && !in_comment && !in_macro) {
                string prefix = "";
                if (current_token == "L" || current_token == "u8" || 
                    current_token == "u" || current_token == "U") {
                    prefix = current_token;
                    current_token.clear();
                }
                
                string str_literal(1, c);
                size_t j = i + 1;
                bool closed = false;
                while (j < content.size()) {
                    char ch = content[j];
                    str_literal += ch;
                    if (ch == c && is_unescaped_quote(j)) {
                        closed = true;
                        break;
                    }
                    j++;
                }
                string whole = prefix + str_literal;
                if (name_map.find(whole) == name_map.end()) {
                    name_map[whole] = generate_random_name();
                }
                result << name_map[whole];
                i = j;
                last_char = ' ';
                continue;
            } 
            else if (in_string && c == quote_char) {
                in_string = false;
            }
            result << c;
            continue;
        }
        
        if (in_string) {
            result << c;
            continue;
        }
        
        if (!in_macro && c == '/' && i+1 < content.size()) {
            if (content[i+1] == '/') {
                in_comment = true;
            } else if (content[i+1] == '*') {
                in_comment = true;
            }
        }
        
        if (in_comment) {
            result << c;
            if (c == '\n' || (c == '*' && i+1 < content.size() && content[i+1] == '/')) {
                in_comment = false;
            }
            continue;
        }
        
        if (c == '#' && !in_string && !in_comment) {
            in_macro = true;
            in_preprocessor = true;
            result << current_token;
            current_token.clear();
            result << c;
            continue;
        }
        
        if (in_macro) {
            result << c;
            if (c == '\n') {
                in_macro = false;
                in_preprocessor = false;
            }
            continue;
        }
        
        if (isalnum(c) || c == '_') {
            current_token += c;
        } else {
            if (!current_token.empty()) {
                if (is_valid_identifier(current_token)) {
                    if (name_map.find(current_token) == name_map.end()) {
                        name_map[current_token] = generate_random_name();
                    }
                    result << name_map[current_token];
                } else {
                    result << current_token;
                }
                current_token.clear();
            }
            result << c;
        }
        last_char = c;
    }
    
    if (!current_token.empty()) {
        if (is_valid_identifier(current_token)) {
            if (name_map.find(current_token) == name_map.end()) {
                name_map[current_token] = generate_random_name();
            }
            result << name_map[current_token];
        } else {
            result << current_token;
        }
    }
    
    stringstream ss1;
    for (auto it = name_map.begin(); it != name_map.end(); ++it) {
        ss1 << "#define " << it->second << " " << it->first << endl;
    }
    content = ss1.str() + result.str();
}

string process_symbols(string content) {
    vector<string> symbols = {
        ">>=", "<<=", "...", "->*", "&&=", "||=", "##",
        "++", "--", "->", "::", "<<", ">>", "<=", ">=", 
        "==", "!=", "&&", "||", "+=", "-=", "*=", "/=", 
        "%=", "&=", "^=", "|=", 
        "!", "$", "%", "&", "(", ")", "*", "+", ",", 
        "-", ".", "/", ":", ";", "<", "=", ">", "?", "[", 
        "]", "^", "{", "|", "}", "~"
    };
    set<string> symbol_set(symbols.begin(), symbols.end());
    bool in_string = false;
    bool in_comment = false;
    char quote_char = 0;
    char comment_type = 0;
    map<string, string> symbol_map;
    set<string> existing_macros;
    stringstream pre_scan(content);
    string line;
    
    // 收集所有已定义的宏名
    while (getline(pre_scan, line)) {
        if (line.find("#define") == 0) {
            size_t start = 7;
            while (start < line.size() && isspace(line[start])) start++;
            size_t end = start;
            while (end < line.size() && !isspace(line[end]) && line[end] != '\r' && line[end] != '\n') end++;
            string macro_name = line.substr(start, end - start);
            if (!macro_name.empty()) {
                existing_macros.insert(macro_name);
            }
        } else {
            break;
        }
    }

    string result_str;
    size_t i = 0;
    const size_t macro_length = 17; // 随机宏名称长度
    
    auto is_unescaped_quote = [&](size_t pos) {
        int backslash_count = 0;
        for (int j = (int)pos - 1; j >= 0 && content[j] == '\\'; --j) {
            backslash_count++;
        }
        return (backslash_count % 2 == 0);
    };

    while (i < content.size()) {
        char c = content[i];
        
        // 处理预处理指令（整行原样输出）
        if (c == '#' && !in_string && !in_comment) {
            result_str += c;
            i++;
            while (i < content.size() && content[i] != '\n') {
                result_str += content[i];
                i++;
            }
            if (i < content.size()) {
                result_str += content[i];
                i++;
            }
            continue;
        }
        
        if ((c == '"' || c == '\'') && is_unescaped_quote(i)) {
            if (!in_string && !in_comment) {
                in_string = true;
                quote_char = c;
            }
            else if (in_string && c == quote_char) {
                in_string = false;
            }
            result_str += c;
            i++;
            continue;
        }
        
        if (in_string) {
            result_str += c;
            i++;
            continue;
        }
        
        if (!in_comment && c == '/' && i + 1 < content.size()) {
            if (content[i+1] == '/') {
                in_comment = true;
                comment_type = '/';
            } else if (content[i+1] == '*') {
                in_comment = true;
                comment_type = '*';
            }
        }
        
        if (in_comment) {
            result_str += c;
            if (comment_type == '/' && c == '\n') {
                in_comment = false;
            } else if (comment_type == '*' && c == '*' && 
                       i + 1 < content.size() && content[i+1] == '/') {
                result_str += content[i+1];
                in_comment = false;
                i += 2;
                continue;
            }
            i++;
            continue;
        }
        
        int max_len = min(static_cast<int>(content.size() - i), 3);
		bool found = false;
		string candidate;
		int len = 0;
		
		// 查找最长的匹配符号
		for (int l = max_len; l >= 1; l--) {
		    candidate = content.substr(i, l);
		    if (symbol_set.find(candidate) != symbol_set.end()) {
		        len = l;
		        found = true;
		        break;
		    }
		}
		
		if (!found) {
		    result_str += c;
		    i++;
		    continue;
		}
		
		bool combined = false;
		string new_macro;
		string combined_symbol;
		
		// 跳过符号后的空白字符
		size_t j = i + len;
		while (j < content.size() && isspace(content[j])) {
		    j++;
		}
		
		// 读取可能的宏名称（有效标识符）
		string possible_macro = "";
		if (j < content.size() && (isalpha(content[j]) || content[j] == '_')) {
		    size_t start = j;
		    while (j < content.size() && (isalnum(content[j]) || content[j] == '_')) {
		        j++;
		    }
		    possible_macro = content.substr(start, j - start);
		}
		
		// 检查是否是已定义的宏
		if (!possible_macro.empty()) {
		    // 组合符号和后面的宏
		    combined_symbol = candidate + possible_macro;
		    
		    // 创建新宏
		    if (symbol_map.find(combined_symbol) == symbol_map.end()) {
		        new_macro = generate_random_name();
		        symbol_map[combined_symbol] = new_macro;
		        existing_macros.insert(new_macro);
		    } else {
		        new_macro = symbol_map[combined_symbol];
		    }
		    
		    // 添加空格确保宏名称不粘连
		    result_str += " " + new_macro + " ";
		    i = j;  // 移动到宏名称之后
		    combined = true;
		}
		
		if (!combined) {
		    // 单独替换符号
		    if (symbol_map.find(candidate) == symbol_map.end()) {
		        new_macro = generate_random_name();
		        symbol_map[candidate] = new_macro;
		        existing_macros.insert(new_macro);
		    } else {
		        new_macro = symbol_map[candidate];
		    }
		    result_str += " " + new_macro + " ";
		    i += len;
		}
    }
    
    stringstream macro_ss;
    for (auto& p : symbol_map) {
        macro_ss << "#define " << p.second << " " << p.first << endl;
    }
    
    return macro_ss.str() + result_str;
}

int main(int argc, char* argv[]) {
    rand_main = mt19937(time(0));
    string s1, s2;
    cout << "CodeObfuscator\nby zfworld hty\n";
    
    if (argc != 3) {
        cerr << "Usage: " << argv[0] << " <input_file> <output_file>" << endl;
        cout << "输入文件名 输出文件名 分两行输入：\n";
        getline(cin, s1);
        getline(cin, s2);
    } else {
        s1 = argv[1];
        s2 = argv[2];
    }
    
    ifstream in_file(s1.c_str());
    if (!in_file) {
        cerr << "Error opening input file" << endl;
        return 1;
    }
    
    string content((istreambuf_iterator<char>(in_file)), 
                   istreambuf_iterator<char>());
    in_file.close();
    
    process_content(content);
    
    string first_part, second_part;
    stringstream ss(content);
    string line;
    
    while (getline(ss, line)) {
        if (line.find("#define") == 0) {
            first_part += line + "\n";
        } else {
            second_part = line;
            break;
        }
    }
    
    while (getline(ss, line)) {
        second_part += "\n" + line;
    }
    
    second_part = process_symbols(second_part);
    content = first_part + second_part;
    
    ofstream out_file(s2.c_str());
    if (!out_file) {
        cerr << "Error opening output file" << endl;
        return 1;
    }
    
    out_file << content;
    out_file.close();
    
    cout << "Obfuscation completed successfully" << endl;
    return 0;
}
